Make gdk_window_present() move the window to the current desktop, instead
authorMatthias Clasen <mclasen@redhat.com>
Mon, 11 Jul 2005 18:28:23 +0000 (18:28 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Mon, 11 Jul 2005 18:28:23 +0000 (18:28 +0000)
2005-07-11  Matthias Clasen  <mclasen@redhat.com>

Make gdk_window_present() move the window to the current
desktop, instead of letting the WM change the current
desktop to where the window is.  (#166379, Elijah Newren)

* gdk/gdk.symbols:
* gdk/x11/gdkx.h:
* gdk/x11/gdkwindow-x11.c (gdk_x11_window_move_to_current_desktop):
New function to move a window to the current desktop.

* gtk/gtkwindow.c (gtk_window_present_with_time): Move the
window to the current desktop before giving it focus.

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-8
gdk/gdk.symbols
gdk/x11/gdkwindow-x11.c
gdk/x11/gdkx.h
gtk/gtkwindow.c

index 8b557e90be46de20c4cb24c6933152df0a0b058d..a3d04a18d2a2d88f715965268fd3c1e75ab3392d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2005-07-11  Matthias Clasen  <mclasen@redhat.com>
+
+       Make gdk_window_present() move the window to the current
+       desktop, instead of letting the WM change the current
+       desktop to where the window is.  (#166379, Elijah Newren)
+       
+       * gdk/gdk.symbols: 
+       * gdk/x11/gdkx.h: 
+       * gdk/x11/gdkwindow-x11.c (gdk_x11_window_move_to_current_desktop): 
+       New function to move a window to the current desktop.
+       
+       * gtk/gtkwindow.c (gtk_window_present_with_time): Move the
+       window to the current desktop before giving it focus.  
+
 2005-07-11  Matthias Clasen  <mclasen@redhat.com>
 
        When dragging text, use a drag icon showing the (ellipsized)
index 8b557e90be46de20c4cb24c6933152df0a0b058d..a3d04a18d2a2d88f715965268fd3c1e75ab3392d 100644 (file)
@@ -1,3 +1,17 @@
+2005-07-11  Matthias Clasen  <mclasen@redhat.com>
+
+       Make gdk_window_present() move the window to the current
+       desktop, instead of letting the WM change the current
+       desktop to where the window is.  (#166379, Elijah Newren)
+       
+       * gdk/gdk.symbols: 
+       * gdk/x11/gdkx.h: 
+       * gdk/x11/gdkwindow-x11.c (gdk_x11_window_move_to_current_desktop): 
+       New function to move a window to the current desktop.
+       
+       * gtk/gtkwindow.c (gtk_window_present_with_time): Move the
+       window to the current desktop before giving it focus.  
+
 2005-07-11  Matthias Clasen  <mclasen@redhat.com>
 
        When dragging text, use a drag icon showing the (ellipsized)
index 8b557e90be46de20c4cb24c6933152df0a0b058d..a3d04a18d2a2d88f715965268fd3c1e75ab3392d 100644 (file)
@@ -1,3 +1,17 @@
+2005-07-11  Matthias Clasen  <mclasen@redhat.com>
+
+       Make gdk_window_present() move the window to the current
+       desktop, instead of letting the WM change the current
+       desktop to where the window is.  (#166379, Elijah Newren)
+       
+       * gdk/gdk.symbols: 
+       * gdk/x11/gdkx.h: 
+       * gdk/x11/gdkwindow-x11.c (gdk_x11_window_move_to_current_desktop): 
+       New function to move a window to the current desktop.
+       
+       * gtk/gtkwindow.c (gtk_window_present_with_time): Move the
+       window to the current desktop before giving it focus.  
+
 2005-07-11  Matthias Clasen  <mclasen@redhat.com>
 
        When dragging text, use a drag icon showing the (ellipsized)
index cfaf57af584d2b6acd33f001d1e1ccd8bdbf0ab6..97f2522ece9a4638f0bcadc52d062d6361193325 100644 (file)
@@ -1181,6 +1181,7 @@ gdkx_visual_get
 
 #if IN_FILE(__GDK_WINDOW_X11_C__)
 gdk_x11_window_set_user_time
+gdk_x11_window_move_to_current_desktop
 #endif
 
 #if IN_FILE(__GDK_XID_C__)
index d939a6345db0cd390995dd4e3f87a3da82a09936..ca82cfc2de14ecf1d51c6266e9b7ea12eea07db9 100644 (file)
@@ -2020,14 +2020,79 @@ gdk_window_lower (GdkWindow *window)
     XLowerWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
 }
 
+/**
+ * gdk_x11_window_move_to_current_desktop:
+ * @window: a #GdkWindow
+ * 
+ * Moves the window to the correct workspace when running under a 
+ * window manager that supports multiple workspaces, as described
+ * in the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended 
+ * Window Manager Hints</ulink>.
+ * 
+ * Since: 2.8
+ */
+void
+gdk_x11_window_move_to_current_desktop (GdkWindow *window)
+{
+  if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
+                                          gdk_atom_intern ("_NET_WM_DESKTOP", FALSE)))
+    {
+      XEvent xev;
+      Atom type;
+      gint format;
+      gulong nitems;
+      gulong bytes_after;
+      guchar *data;
+      gulong *current_desktop;
+      GdkDisplay *display;
+      
+      display = gdk_drawable_get_display (window);
+
+      /* Get current desktop, then set it; this is a race, but not
+       * one that matters much in practice.
+       */
+      XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                          GDK_WINDOW_XROOTWIN (window),
+                         gdk_x11_get_xatom_by_name_for_display (display, "_NET_CURRENT_DESKTOP"),
+                          0, G_MAXLONG,
+                          False, XA_CARDINAL, &type, &format, &nitems,
+                          &bytes_after, &data);
+
+      if (type == XA_CARDINAL)
+        {
+         current_desktop = (gulong *)data;
+         
+          xev.xclient.type = ClientMessage;
+          xev.xclient.serial = 0;
+          xev.xclient.send_event = True;
+          xev.xclient.window = GDK_WINDOW_XWINDOW (window);
+         xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP");
+          xev.xclient.format = 32;
+
+          xev.xclient.data.l[0] = *current_desktop;
+          xev.xclient.data.l[1] = 0;
+          xev.xclient.data.l[2] = 0;
+          xev.xclient.data.l[3] = 0;
+          xev.xclient.data.l[4] = 0;
+      
+          XSendEvent (GDK_DISPLAY_XDISPLAY (display), 
+                      GDK_WINDOW_XROOTWIN (window), 
+                      False,
+                      SubstructureRedirectMask | SubstructureNotifyMask,
+                      &xev);
+
+          XFree (current_desktop);
+        }
+    }
+}
+
 /**
  * gdk_window_focus:
  * @window: a #GdkWindow
  * @timestamp: timestamp of the event triggering the window focus
  *
- * Sets keyboard focus to @window. If @window is not onscreen this
- * will not work. In most cases, gtk_window_present() should be used on
- * a #GtkWindow, rather than calling this function.
+ * Sets keyboard focus to @window. In most cases, gtk_window_present() 
+ * should be used on a #GtkWindow, rather than calling this function.
  * 
  **/
 void
@@ -5785,9 +5850,8 @@ emulate_move_drag (GdkWindow     *window,
  * Begins a window resize operation (for a toplevel window).
  * You might use this function to implement a "window resize grip," for
  * example; in fact #GtkStatusbar uses it. The function works best
- * with window managers that support the Extended Window Manager Hints spec
- * (see http://www.freedesktop.org), but has a fallback implementation
- * for other window managers.
+ * with window managers that support the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended Window Manager Hints</ulink>, but has a 
+ * fallback implementation for other window managers.
  * 
  **/
 void
@@ -5821,8 +5885,8 @@ gdk_window_begin_resize_drag (GdkWindow     *window,
  * Begins a window move operation (for a toplevel window).  You might
  * use this function to implement a "window move grip," for
  * example. The function works best with window managers that support
- * the Extended Window Manager Hints spec (see
- * http://www.freedesktop.org), but has a fallback implementation for
+ * the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended 
+ * Window Manager Hints</ulink>, but has a fallback implementation for
  * other window managers.
  * 
  **/
index ac6ee4442116f76c17b91f989f011c795c729aae..1e9f1f1fb1e41bf3a73afefbe147a42bc87e83ad 100644 (file)
@@ -55,6 +55,7 @@ Screen * gdk_x11_screen_get_xscreen       (GdkScreen   *screen);
 int      gdk_x11_screen_get_screen_number (GdkScreen   *screen);
 void     gdk_x11_window_set_user_time     (GdkWindow   *window,
                                           guint32      timestamp);
+void     gdk_x11_window_move_to_current_desktop (GdkWindow   *window);
 
 const char* gdk_x11_screen_get_window_manager_name (GdkScreen *screen);
 
@@ -154,7 +155,6 @@ gpointer      gdk_xid_table_lookup   (XID              xid);
 gboolean      gdk_net_wm_supports    (GdkAtom    property);
 void          gdk_x11_grab_server    (void);
 void          gdk_x11_ungrab_server  (void);
-
 #endif
 
 GdkDisplay   *gdk_x11_lookup_xdisplay (Display *xdisplay);
index 9811973344cf658fdec4385263eaadf02dc93cae..8f0365c2ddea21f9da8c9a3ef04e935e0a230bba 100644 (file)
@@ -6007,17 +6007,7 @@ gtk_window_set_frame_dimensions (GtkWindow *window,
 void
 gtk_window_present (GtkWindow *window)
 {
-  guint32 timestamp;
-#ifdef GDK_WINDOWING_X11
-  GdkDisplay *display;
-
-  display = gtk_widget_get_display (GTK_WIDGET (window));
-  timestamp = gdk_x11_display_get_user_time (display);
-#else
-  timestamp = gtk_get_current_event_time ();
-#endif
-  
-  gtk_window_present_with_time (window, timestamp);
+  gtk_window_present_with_time (window, GDK_CURRENT_TIME);
 }
 
 /**
@@ -6048,9 +6038,22 @@ gtk_window_present_with_time (GtkWindow *window,
       
       gdk_window_show (widget->window);
 
-      /* note that gdk_window_focus() will also move the window to
-       * the current desktop, for WM spec compliant window managers.
-       */
+      /* Translate a timestamp of GDK_CURRENT_TIME appropriately */
+      if (timestamp == GDK_CURRENT_TIME)
+        {
+#ifdef GDK_WINDOWING_X11
+          GdkDisplay *display;
+
+          display = gtk_widget_get_display (GTK_WIDGET (window));
+          timestamp = gdk_x11_display_get_user_time (display);
+#else
+          timestamp = gtk_get_current_event_time ();
+#endif
+        }
+
+#ifdef GDK_WINDOWING_X11
+      gdk_x11_window_move_to_current_desktop (widget->window);
+#endif
       gdk_window_focus (widget->window, timestamp);
     }
   else